from fastapi import FastAPI, HTTPException, status
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
import logging
import sys
import os
from pathlib import Path
from contextlib import asynccontextmanager

from config.settings import settings
from src.middleware import (
    error_handler_middleware, 
    request_logger_middleware, 
    response_formatter_middleware,
    rate_limiter_middleware,
    authentication_middleware,
    security_headers_middleware
)

# Configure logging
logging.basicConfig(
    level=getattr(logging, settings.log_level.upper()),
    format=settings.log_format,
    handlers=[
        logging.StreamHandler(sys.stdout),
        logging.FileHandler("app.log")
    ]
)

logger = logging.getLogger(__name__)

# Ensure upload directory exists
os.makedirs(settings.upload_path, exist_ok=True)

# Create lifespan context manager for startup/shutdown
@asynccontextmanager
async def lifespan(app: FastAPI):
    """Manage application lifespan (startup and shutdown)"""
    # Startup
    logger.info("Starting application initialization...")
    
    if settings.enable_cache:
        from src.utils.cache_manager import initialize_cache
        cache_success = await initialize_cache(
            redis_url=settings.redis_url,
            default_ttl=settings.cache_ttl,
            max_cache_size=settings.max_cache_size
        )
        if cache_success:
            logger.info("Redis cache initialized successfully")
        else:
            logger.warning("Failed to initialize Redis cache - continuing without caching")
    
    if settings.enable_file_cleanup:
        from src.utils.file_cleanup import initialize_file_cleanup
        from pathlib import Path
        initialize_file_cleanup(
            upload_dir=Path(settings.upload_path),
            max_storage_size=settings.max_storage_size,
            max_file_age_hours=settings.max_file_age_hours,
            cleanup_interval_minutes=settings.cleanup_interval_minutes,
            enable_quota_management=settings.enable_quota_management,
            start_background=True
        )
        logger.info("File cleanup manager initialized successfully")
    
    # Initialize AI service with available API keys
    try:
        from src.services import initialize_ai_service
        ai_initialized = await initialize_ai_service(
            openai_api_key=settings.openai_api_key,
            openai_base_url=settings.openai_base_url,
            anthropic_api_key=settings.anthropic_api_key
        )
        if ai_initialized:
            logger.info("AI service initialized successfully")
        else:
            logger.warning("AI service initialization failed - no valid API keys provided")
    except Exception as e:
        logger.error(f"Failed to initialize AI service: {e}")
    
    logger.info("Application startup completed")
    
    # Application is running
    yield
    
    # Shutdown
    logger.info("Starting application shutdown...")
    
    if settings.enable_cache:
        from src.utils.cache_manager import cleanup_cache
        await cleanup_cache()
        logger.info("Cache manager shut down")
    
    if settings.enable_file_cleanup:
        from src.utils.file_cleanup import shutdown_file_cleanup
        await shutdown_file_cleanup()
        logger.info("File cleanup manager shut down")
    
    logger.info("Application shutdown completed")

# Create FastAPI application
app = FastAPI(
    title=settings.app_name,
    version=settings.app_version,
    description="基于大模型的教室借用智能审核系统，支持MCP协议和OpenAI兼容API",
    debug=settings.debug,
    lifespan=lifespan,  # Add lifespan context manager
    docs_url="/docs",
    redoc_url="/redoc",
    openapi_url="/openapi.json",
    contact={
        "name": "TeachWorkflow API Support",
        "email": "support@teachworkflow.com"
    },
    license_info={
        "name": "MIT License",
        "url": "https://opensource.org/licenses/MIT"
    },
    servers=[
        {"url": "http://localhost:8000", "description": "Development server"},
        {"url": "https://flow.yinzishu.com", "description": "Production server"}
    ],
    tags_metadata=[
        {
            "name": "MCP Protocol",
            "description": "Model Context Protocol endpoints for tool calling and integration"
        },
        {
            "name": "OpenAI Compatible API",
            "description": "OpenAI-compatible chat completion endpoints with streaming support"
        },
        {
            "name": "File Management",
            "description": "File upload, processing and management operations"
        },
        {
            "name": "Classroom Management",
            "description": "Classroom booking and management operations"
        },
        {
            "name": "grading",
            "description": "智能评分系统：支持AI自动评分、关键词标记、批改建议生成"
        },
        {
            "name": "HiAgent Chat",
            "description": "HiAgent对话系统：对话管理、聊天功能、消息历史、流式响应"
        },
        {
            "name": "HiAgent Center",
            "description": "HiAgent智能体中心：应用中心浏览、个人智能体管理、收藏功能、智能体创建与编辑"
        },
        {
            "name": "HiAgent Plugins",
            "description": "HiAgent插件中心：插件浏览、安装、配置、收藏管理"
        },
        {
            "name": "HiAgent Knowledge",
            "description": "HiAgent知识库管理：知识库创建、编辑、删除、查询、文档管理"
        },
        {
            "name": "Models",
            "description": "模型查询管理：获取可用模型列表、搜索模型、查看模型统计信息"
        },
        {
            "name": "AIPPT",
            "description": "AIPPT PPT生成：模板管理、PPT生成、文件管理、一键生成PPT"
        },
        {
            "name": "HiAgent Workspace",
            "description": "HiAgent工作空间管理：通过用户名获取工作空间ID、用户信息查询"
        },
        {
            "name": "Smart Review",
            "description": "智能批阅系统：支持多种文档类型的智能批阅、评分、反馈生成"
        }
    ]
)

# Add middleware (order matters - first added is outermost)
# Security headers (outermost)
app.add_middleware(
    security_headers_middleware(add_security_headers=True)
)

# Response formatter 
app.add_middleware(
    response_formatter_middleware(
        format_responses=True,
        add_metadata=not settings.debug  # Less verbose in production
    )
)

# Request logger
app.add_middleware(
    request_logger_middleware(
        log_requests=True,
        log_responses=True
    )
)

# Error handler
app.add_middleware(
    error_handler_middleware(debug=settings.debug)
)

# Rate limiting
app.add_middleware(
    rate_limiter_middleware(
        enabled=settings.enable_rate_limiting,
        requests_per_window=settings.rate_limit_requests,
        window_seconds=settings.rate_limit_window,
        ip_whitelist=settings.ip_whitelist,
        skip_paths=["/docs", "/redoc", "/openapi.json", "/health", "/"]
    )
)

# Authentication
app.add_middleware(
    authentication_middleware(
        enabled=settings.enable_auth,
        api_key=settings.api_key,
        api_key_header=settings.api_key_header,
        skip_paths=["/docs", "/redoc", "/openapi.json", "/health", "/"],
        public_paths=[]  # Add public paths that don't require auth when enabled
    )
)

# CORS middleware (innermost, closest to routes)
app.add_middleware(
    CORSMiddleware,
    allow_origins=settings.cors_origins,
    allow_credentials=settings.cors_credentials,
    allow_methods=settings.cors_methods,
    allow_headers=settings.cors_headers,
)

# Include routers
try:
    from src.routers.files import router as files_router
    from src.routers.classroom import router as classroom_router
    from src.routers.audit_router import router as audit_router
    from src.routers.mcp import router as mcp_router
    from src.routers.openai import router as openai_router
    from src.routers.upload import router as upload_router
    from src.routers.course import router as course_router
    from src.routers.grading import router as grading_router
    from src.routers.hiagent_chat import router as hiagent_chat_router
    from src.routers.hiagent_center import router as hiagent_center_router
    from src.routers.hiagent_center_plugins import router as hiagent_plugins_router
    from src.routers.hiagent_knowledge import router as hiagent_knowledge_router
    from src.routers.models import router as models_router
    from src.routers.agent_publish import router as agent_publish_router
    from src.routers.aippt import router as aippt_router
    from src.routers.hiagent_workspace import router as hiagent_workspace_router
    from src.routers.smart_review import router as smart_review_router

    app.include_router(files_router)
    app.include_router(classroom_router)
    app.include_router(audit_router)
    app.include_router(mcp_router)
    app.include_router(openai_router)
    app.include_router(upload_router)
    app.include_router(course_router)
    app.include_router(grading_router)
    app.include_router(hiagent_chat_router)
    app.include_router(hiagent_center_router)
    app.include_router(models_router)
    app.include_router(hiagent_plugins_router)
    app.include_router(hiagent_knowledge_router)
    app.include_router(agent_publish_router)
    app.include_router(aippt_router)
    app.include_router(hiagent_workspace_router)
    app.include_router(smart_review_router)
    logger.info("路由器加载成功")
except Exception as e:
    logger.error(f"路由器加载失败: {str(e)}")

@app.get("/")
async def root():
    """Root endpoint providing API information."""
    return {
        "message": f"欢迎使用{settings.app_name}",
        "version": settings.app_version,
        "status": "running",
        "docs_url": "/docs",
        "redoc_url": "/redoc"
    }

@app.get("/health")
async def health_check():
    """Health check endpoint."""
    return {
        "status": "healthy",
        "version": settings.app_version,
        "timestamp": "2025-09-07T01:45:00Z"
    }

@app.get("/api/v1/info")
async def api_info():
    """API information endpoint."""
    return {
        "api_version": "v1",
        "app_name": settings.app_name,
        "app_version": settings.app_version,
        "supported_file_types": settings.allowed_file_types,
        "max_file_size_mb": settings.max_file_size // (1024 * 1024),
        "features": [
            "MCP协议支持",
            "OpenAI格式API",
            "多格式文件解析",
            "大模型集成",
            "教室借用审核"
        ]
    }

# Exception handlers are now managed by ErrorHandlerMiddleware